<!--
 * @Description:
 * @Author: william
 * @Date: 2025-02-17 16:47:40
 * @LastEditors: william
 * @LastEditTime: 2025-06-03 11:55:50
-->
<template>
  <BaseDialog
    v-model="dialogVisible"
    :title="g_t('fleet.vehicleScheduleOptimize')"
    width="80vw"
    style="max-width: 1000px"
    :before-close="handleClose"
  >
    <div v-loading="btnLoading">
      <el-row type="flex" justify="space-between" class="dialog-table-filter">
        <div class="row-left">
          <DateTimeRange
            v-model="timePeriod"
            class="item"
            type="daterange"
            :clearable="false"
            picker-type="2"
            :disabled-date="disabledDate"
          />
          <el-button type="primary" @click="handleQuery">{{
            $t('public.search')
          }}</el-button>
          <!-- <el-button plain @click="handleReset">{{
          $t('public.reset')
        }}</el-button> -->
          <el-button plain type="primary" @click="handleVehicleOptimize">{{
            $t('fleet.vehicleScheduleOptimize')
          }}</el-button>
        </div>
        <!-- <div class="row-right"> -->
        <!-- <Date
            v-model="searchTime"
            class="item"
            style="width: 150px; min-width: 150px"
            :clearable="false"
          /> -->
        <!-- <el-select
          v-model="listParams.year"
          style="width: 90px; margin-left: 5px"
          :placeholder="g_t('public.year')"
        >
          <el-option
            v-for="year in yearOptions"
            :key="year"
            :label="year + g_t('public.year')"
            :value="year"
          />
        </el-select>
        <el-select
          v-model="listParams.month"
          style="width: 90px; margin-left: 5px"
          :placeholder="g_t('public.month')"
        >
          <el-option
            v-for="month in monthOptions"
            :key="month"
            :label="month + g_t('public.month')"
            :value="month"
          />
        </el-select>
        <el-select
          v-model="listParams.day"
          style="width: 90px; margin-left: 5px"
          :placeholder="g_t('public.day')"
        >
          <el-option
            v-for="day in dayOptions"
            :key="day"
            :label="day + g_t('public.day')"
            :value="day"
          />
        </el-select> -->
        <!-- </div> -->
      </el-row>
      <div v-loading="viewLoading" class="calendar-container">
        <FullCalendar
          ref="fullCalendar"
          class="full-calendar-container"
          :options="calendarOptions"
        />
      </div>
    </div>
    <template #footer>
      <div class="form-dialog-footer">
        <el-button plain @click="handleClose">{{
          $t('public.close')
        }}</el-button>
        <el-button plain type="primary" @click="handleConfirm">{{
          $t('public.confirm')
        }}</el-button>
      </div>
    </template>
  </BaseDialog>
</template>

<script setup>
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import timeGridPlugin from '@fullcalendar/timegrid'
import resourceTimelinePlugin from '@fullcalendar/resource-timeline'

const emit = defineEmits(['update'])
const dialogVisible = defineModel({
  type: Boolean,
  default: false
})

const timePeriod = ref([
  // g_dayjs().format('YYYY-MM-DD 00:00:00'),
  // g_dayjs().format('YYYY-MM-DD 23:59:59')
  g_dayjs().startOf('week').format('YYYY-MM-DD 00:00:00'),
  g_dayjs().endOf('week').format('YYYY-MM-DD 23:59:59')
])
const duration = computed(() => {
  return g_dayjs(timePeriod.value[1]).diff(timePeriod.value[0], 'day') + 1
})
const btnLoading = ref(false)
const searchTime = ref(g_dayjs().format('YYYY-MM-DD'))
// let minDate = ref(g_dayjs().subtract(20, 'year'))
// let maxDate = ref(g_dayjs().add(20, 'year'))
// const listParams = ref({
//   year: g_dayjs().year(),
//   month: g_dayjs().month() + 1,
//   day: g_dayjs().date()
// })
const fullCalendar = ref(null)
const viewLoading = ref(false)
const calendarOptions = ref({
  plugins: [
    dayGridPlugin,
    interactionPlugin,
    timeGridPlugin,
    resourceTimelinePlugin
  ],
  locale: 'zh-cn', // zh-cn en
  initialView: 'resourceTimelineWeek',
  allDaySlot: false,
  // axisFormat: 'h(:mm)tt',
  // headerToolbar: {
  //   // left: 'prev,next',
  //   // right: 'title'
  //   // left: 'prev,next today',
  //   // center: 'title',
  //   // right: 'resourceTimelineDay,resourceTimelineWeek,timeGridWeek,dayGridMonth'
  // },
  headerToolbar: false,
  buttonText: {
    // today: '今天',
    // day: '日',
    // week: '周',
    // month: '月',
    // prev: g_t('public.lastMonth'),
    // next: g_t('public.nextMonth')
    // prev: '上个视图',
    // next: '下个视图'
  },
  // 时间轴间距
  slotMinTime: '00:00:00', // 最小时间
  slotMaxTime: '24:00:00', // 最大时间
  // 单个时间的时间间隔
  slotDuration: '24:00:00',
  slotLabelContent: arg => {
    // return { html: `<div style="min-width:150px">${arg.text}</div>` }
    return (
      g_dayjs(arg.date).format('M/DD') +
      ' ' +
      g_options.getOptionText(
        g_options.dateDayOptions,
        g_dayjs(arg.date).day(),
        ''
      )
    )
  },
  views: {
    resourceTimelineWeek: {
      // buttonText: '天',
      type: 'resourceTimelineWeek',
      duration: { days: 1 } // 设置为一天的视图
    }
  },
  resourceAreaColumns: [
    {
      headerContent: g_t('fleet.orderCarInfo')
    }
  ],
  resourceAreaWidth: '150px',
  resources: [
    // {
    //   id: 'a',
    //   title: '山水国际<br>深圳市-深圳市'
    // }
  ],
  resourceLabelContent: arg => {
    return { html: arg.resource.title }
  },
  initialDate: searchTime.value, // 初始化日期
  events: [
    // {
    //   resourceId: 'a', // 事件的唯一标识符
    //   title: '标题bbb', // 事件的标题
    //   start: '2025-05-09 01:00:00', // 事件的开始时间（ISO 8601 格式）
    //   end: '2025-05-10 03:10:00' // 事件的结束时间（ISO 8601 格式）
    // }
  ],
  eventContent: arg => {
    return { html: arg.event.title }
  },
  // 设置可见的日期范围为昨天到今天
  // visibleRange: currentDate => {
  //   return {
  //     start: yesterday.toISOString().substring(0, 10), // 截取字符串以去除时间部分
  //     end: today.toISOString().substring(0, 10)
  //   }
  // },
  // visibleRange: {
  //   start: '2025-05-09',
  //   end: '2025-05-25'
  // },
  slotLabelFormat: {
    hour: 'numeric',
    minute: '2-digit',
    hour12: false
  },
  eventTimeFormat: {
    hour: 'numeric',
    minute: '2-digit',
    hour12: false
  },
  viewDidMount: (view, el) => {
    // console.log('viewDidMount', view, el)
  },
  eventClick: events => {
    console.log('eventClick', events.event)
  },
  datesSet: info => {
    // console.log('datesSet', info)
    // 确保DOM元素已渲染完毕
    nextTick(() => {
      // 找到时间轴容器并滚动到最左边
      document.querySelectorAll('.fc-scroller').forEach(item => {
        item.scrollLeft = 0
        item.scrollTop = 0
      })
    })
  }
})
const scheduleList = ref([])

// watch(
//   () => searchTime.value,
//   nv => {
//     handleQuery()
//     fullCalendar.value?.getApi().gotoDate(nv)
//   }
// )

// watch(
//   () => timePeriod.value,
//   nv => {
//     minDate.value = g_dayjs(nv.length ? nv[0] : new Date())
//     maxDate.value = g_dayjs(nv.length ? nv[1] : new Date())
//     listParams.value = {
//       year: minDate.value.year(),
//       month: minDate.value.month() + 1,
//       day: minDate.value.date()
//     }
//   },
//   {
//     immediate: true,
//     deep: true
//   }
// )

// // 计算年份选项
// const yearOptions = computed(() => {
//   return Array.from(
//     { length: maxDate.value.year() - minDate.value.year() + 1 },
//     (_, i) => minDate.value.year() + i
//   )
// })

// const monthOptions = computed(() => {
//   const { year, month } = listParams.value
//   const validMonths = []

//   for (let month2 = 1; month2 <= 12; month2++) {
//     const date = g_dayjs(`${year}-${month2}-01`, 'YYYY-M-DD') // 当月的第一天
//     const lastDayOfMonth = date.endOf('month') // 当月最后一天
//     // 如果当月第一天 > 最大日期 或者 当月最后一天 < 最小日期，则跳过
//     if (date.isAfter(maxDate.value, 'month')) break
//     if (lastDayOfMonth.isBefore(minDate.value, 'month')) continue
//     // 否则说明该月与时间范围有交集
//     validMonths.push(month2)
//   }
//   if (validMonths.indexOf(month) === -1) listParams.value.month = validMonths[0]

//   return validMonths
// })

// // 计算可用天数
// const dayOptions = computed(() => {
//   const { year, month, day } = listParams.value

//   const startDate = g_dayjs(`${year}-${month}-01`)
//   const endDate = startDate.endOf('month')

//   const validStartDay = startDate.isAfter(minDate.value, 'day')
//     ? startDate.date()
//     : minDate.value.date()
//   const validEndDay = endDate.isBefore(maxDate.value, 'day')
//     ? endDate.date()
//     : maxDate.value.date()

//   const validDays = Array.from(
//     { length: validEndDay - validStartDay + 1 },
//     (_, i) => i + validStartDay
//   )
//   if (validDays.indexOf(day) === -1) listParams.value.day = validDays[0]

//   return validDays
// })

onMounted(() => {
  nextTick(() => {
    getTableList()
    fullCalendar.value?.getApi().updateSize()
  })
})

const getTableList = () => {
  viewLoading.value = true
  const calendarApi = fullCalendar.value?.getApi()
  calendarApi.gotoDate(timePeriod.value[0] || new Date())
  calendarOptions.value.resources = []
  calendarOptions.value.events = []
  g_api.fleet
    .apiOrderQueryVehicle({
      startTime: g_dayjs(timePeriod.value[0] || new Date()).format(
        'YYYY-MM-DD 00:00:00'
      ),
      endTime: g_dayjs(timePeriod.value[1] || new Date()).format(
        'YYYY-MM-DD 23:59:59'
      )
    })
    .then(({ code, data }) => {
      if (code === '200' && data) {
        setCalendarOptions(data)
        const currentViews = calendarApi.getOption('views')
        currentViews.resourceTimelineWeek.duration = {
          days: duration.value
        }
        // 使用 setOption 更新整个 views 配置
        calendarApi.setOption('views', currentViews)
        // 刷新视图以应用更改
        calendarApi.render() // 或者使用 calendarApi.updateSize() 根据需求
      }
    })
    .finally(_ => {
      viewLoading.value = false
    })
}

const setCalendarOptions = data => {
  calendarOptions.value.resources = data.map(item => {
    return {
      id: item.orderId,
      title: `${item.customer}<br>${item.trip}`
    }
  })
  calendarOptions.value.events = data.flatMap(item => {
    return (item.vehicleScheduleList || []).map(info => {
      return {
        className: 'custom-evnet-class',
        color: '#6fba2c', // Event的背景颜色
        resourceId: item.orderId,
        vehicleId: info.vehicleId,
        title: `
                ${item.customer}<br>${item.trip}<br>
                ${g_dayjs(info.startTime).format('M-DD HH:mm')}
                ~
                ${g_dayjs(info.endTime).format('M-DD HH:mm')}
                ${info.vehiclePlate ? '<br>' + info.vehiclePlate : ''}
              `,
        start: info.startTime,
        end: info.endTime
      }
    })
  })
}

const handleClose = () => {
  dialogVisible.value = false
}

const disabledDate = time => {
  return false
}

const handleQuery = () => {
  getTableList()
}

// const handleReset = () => {
//   timePeriod.value = []
//   handleQuery()
// }

const handleVehicleOptimize = () => {
  if (!timePeriod.value.length) {
    return ElMessage({
      message: g_t('fleet.selectDispatchTimeRange'),
      type: 'warning'
    })
  }
  btnLoading.value = true
  g_api.fleet
    .apiOrderOptimizeVehicle({
      // type: '2',
      startTime: timePeriod.value[0] || '',
      endTime: timePeriod.value[1] || ''
    })
    .then(res => {
      if (res.code === '200' && res.data) {
        ElMessage({
          message: res.message,
          type: 'success'
        })
        setCalendarOptions(res.data)
        scheduleList.value = res.data
      }
    })
    .finally(_ => {
      btnLoading.value = false
    })
}

const handleConfirm = () => {
  // if (!scheduleList.value.length) {
  //   return ElMessage({
  //     message: '请先进行排车优化!',
  //     type: 'warning'
  //   })
  // }
  btnLoading.value = true
  g_api.fleet
    .apiOrderConfirmVehicle({
      scheduleList: scheduleList.value
    })
    .then(res => {
      if (res.code === '200') {
        ElMessage({
          message: res.message,
          type: 'success'
        })
        handleClose()
        emit('update')
      }
    })
    .finally(_ => {
      btnLoading.value = false
    })
}
</script>

<style scoped lang="scss">
.dialog-table-filter {
  margin-bottom: 0;
}
.full-calendar-container {
  height: calc(100vh - 100px - 66px - 77px);
  :deep(.fc-license-message) {
    display: none;
  }
  :deep(.fc-header-toolbar) {
    margin-bottom: 5px;
  }
  // :deep() {
  //   .fc-col-header-cell-cushion {
  //     min-width: 100px;
  //   }
  //   .fc-daygrid-day {
  //     min-width: 100px;
  //     border: 2px solid red;
  //   }
  // }
  :deep() {
    .fc-prev-button,
    .fc-next-button {
      background-color: var(--button-bg);
      color: var(--button-text-color);
      border-color: var(--button-border-color);
      border-radius: 5px;
      box-shadow: none !important;
      &:not(:disabled):active {
        background-color: var(--button-bg);
        color: var(--button-text-color);
        border-color: var(--button-border-color);
      }
      &:not(:disabled):active:focus {
        box-shadow: none;
      }
    }

    .fc-next-button {
      position: relative;
      &::before {
        display: block;
        content: '';
        position: absolute;
        width: 1px;
        height: 50%;
        top: 50%;
        transform: translateY(-50%);
        left: 0;
        background-color: white;
      }
    }

    .fc-prev-button:hover,
    .fc-next-button:hover {
      opacity: 0.6;
    }
  }
}
.form-dialog-footer {
  margin-top: 10px;
}
</style>
